package com.noahplat.user.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.noahplat.common.utils.*;
import com.noahplat.person.feign.PersonFeign;
import com.noahplat.user.mapper.*;
import com.noahplat.user.pojo.*;
import com.noahplat.user.utils.PasswordDao;
import com.noahplat.user.utils.UserDao;
import com.noahplat.user.service.UserService;
import io.seata.spring.annotation.GlobalTransactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import tk.mybatis.mapper.entity.Example;

import javax.validation.constraints.NotEmpty;
import java.util.*;
import java.util.regex.Pattern;

/**
 * 作者：李景星
 * 描述：用户服务实现类
 * 时间：2020-10-31
 */
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private RedisUtils redisUtils;

    @Autowired
    private UserRoleMapper userRoleMapper;
    @Autowired
    private MenuMapper menuMapper;
    @Autowired
    private PermissionMapper permissionMapper;
    @Autowired
    private RolePermissionMapper rolePermissionMapper;
    @Autowired
    private RoleMenuMapper roleMenuMapper;

    @Autowired
    private PersonFeign personFeign;

    @Autowired
    private AvatarMapper avatarMapper;

    @Autowired
    private RoleMapper roleMapper;

    /**
     * 作者：李景星
     * 描述：通过用户名查询用户信息
     * 时间：2020-10-31
     *
     * @param username
     * @return
     */
    @Override
    public Result<User> queryUserByUsername(String username) {
        Example example = new Example(User.class);
        example.createCriteria().andEqualTo("username", username);
        User user = userMapper.selectOneByExample(example);
        if (ObjectUtils.isEmpty(user)) {
            return new Result(true, StatusCode.NOTFOUNDERROR, "该用户不存在！");
        }
        return new Result<User>(true, StatusCode.OK, "查询成功！", user);
    }


    /**
     * 通过Id修改用户信息
     *
     * @param name
     * @param email
     * @return
     * @author 李东
     * @date 2021-02-25
     */
    @Override
    public Result updateUserInfo(String name, String email, String phone, Long uid) {
        //获取用户信息
        Example example = new Example(User.class);
        example.createCriteria().andEqualTo("id", uid);
        User user = userMapper.selectOneByExample(example);
        if (ObjectUtils.isEmpty(user) || "Y".equals(user.getDel().toString())) {
            return new Result(true, StatusCode.NOTFOUNDERROR, "该用户不存在或已被注销！");
        }
        //修改用户信信息
        user.setName(name);
        user.setEmail(email);
        user.setPhone(phone);
        Example upExample = new Example(User.class);
        upExample.createCriteria().andEqualTo("id", user.getId());
        int i = userMapper.updateByExampleSelective(user, upExample);
        if (i == 0) {
            return new Result(true, StatusCode.SERVER_EXCEPTION, "服务器异常！");
        }
        return new Result<User>(true, StatusCode.OK, "操作成功！");
    }

    /**
     * 修改账户密码
     *
     * @param oldPassword
     * @param password
     * @return
     */
    @Override
    public Result updatePassword(String oldPassword, String password, Long uid) {
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        //通过token获取用户信
        Example example = new Example(User.class);
        example.createCriteria().andEqualTo("id", uid);
        User user = userMapper.selectOneByExample(example);
        if (!passwordEncoder.matches(oldPassword, user.getPassword())) {
            return new Result(true, StatusCode.ERROR, "输入的原密码错误！");
        }
        //验证通过修改密码
        User newUser = new User();
        newUser.setPassword(passwordEncoder.encode(password));
        int i = userMapper.updateByExampleSelective(newUser, example);
        if (0 == i) {
            return new Result(true, StatusCode.SERVER_EXCEPTION, "服务器异常！");
        }
        return new Result<User>(true, StatusCode.OK, "修改成功！");
    }

    @GlobalTransactional
    @Override
    public Result register(UserDao userDao) {
        //注册账号-手机号校验
        Example example = new Example(User.class);
        example.createCriteria().orEqualTo("username", userDao.getPhone());
        example.and(example.createCriteria().andEqualTo("stid", userDao.getStid()));
        User u = userMapper.selectOneByExample(example);
        if (!ObjectUtils.isEmpty(u)) {
            redisUtils.del(NoahEnum.REGCODEDIR.getCode() + userDao.getPhone());
            return new Result(true, StatusCode.ERROR, "该账户已被注册！");
        }
        Example example1 = new Example(User.class);
        example1.createCriteria().andEqualTo("phone", userDao.getPhone());
        example1.and(example1.createCriteria().andEqualTo("stid", userDao.getStid()));
        User user1 = userMapper.selectOneByExample(example1);
        if (!ObjectUtils.isEmpty(user1)) {
            return new Result(true, StatusCode.ERROR, "该手机号已被绑定！");
        }
        //手机验证码校验
        boolean hasKey = redisUtils.hasKey(NoahEnum.REGCODEDIR.getCode() + userDao.getPhone());
        if (!hasKey) {
            return new Result(true, StatusCode.ERROR, "验证码已失效！");
        }
        String smsCode = (String) redisUtils.get(NoahEnum.REGCODEDIR.getCode() + userDao.getPhone());
        if (!smsCode.equals(userDao.getSms())) {
            return new Result(true, StatusCode.ERROR, "验证码输入有误！");
        }
        //登记数据
        User user = new User();
        user.setUsername(userDao.getPhone());
        user.setPassword(MD5Utils.getMD5Pwd(userDao.getPassword()));
        user.setDel('N');
        user.setName(userDao.getPhone());
        user.setCreatedTime(new Date());
        user.setPhone(userDao.getPhone());
        user.setUserType(userDao.getUserType());
        user.setAcctid(Long.parseLong("1"));
        user.setUserPro(userDao.getUserPro());
        user.setEmail("");
        user.setStid(Long.parseLong(userDao.getStid()));
        //新增头像关联操作,默认查询第一个头像 - 2021-03-08 -李东
        Avatar avatar = avatarMapper.selectOneByStid(Long.parseLong(userDao.getStid()));
        if (!ObjectUtils.isEmpty(avatar)) {
            user.setAvatar(avatar.getImage());
        }
        //
        int i = userMapper.insertSelective(user);
        if (i <= 0) {
            return new Result(true, StatusCode.SERVER_EXCEPTION, "服务器异常！");
        }
        //同步注册权限
        UserRole userRole = new UserRole();
        userRole.setUid(user.getId());
        userRole.setRid(Long.parseLong("1"));
        int a = userRoleMapper.insert(userRole);
        if (a == 0) {
            return new Result(true, StatusCode.SERVER_EXCEPTION, "服务器异常！");
        }
        //同步初始化person
        Long userId = user.getId();
        Result result = personFeign.initPerson(userId);
        Object resultData = result.getData();
        if (ObjectUtils.isEmpty(resultData)) {
            return new Result<User>(true, StatusCode.OK, "服务器异常！");
        }
        //更新Id
        Example userExp = new Example(User.class);
        userExp.createCriteria().andEqualTo("id", user.getId());
        user.setPid(Long.parseLong(resultData.toString()));
        int upStatus = userMapper.updateByExampleSelective(user, userExp);
        if (upStatus == 0) {
            return new Result(true, StatusCode.SERVER_EXCEPTION, "服务器异常！");
        }
        return new Result<User>(true, StatusCode.OK, "恭喜您，注册成功！");
    }

    /**
     * 根据Id 修改用户信息 -有值则修改
     *
     * @param user
     * @return
     */
    @Override
    public Result updateUserById(User user) {
        Example example = new Example(User.class);
        example.createCriteria().andEqualTo("id", user.getId());
        User userRes = userMapper.selectOneByExample(example);
        if (ObjectUtils.isEmpty(userRes) || "Y".equals(userRes.getDel().toString())) {
            return new Result(true, StatusCode.NOTFOUNDERROR, "该用户不存在或已被注销！");
        }
        int a = userMapper.updateByExampleSelective(user, example);
        if (a == 0) {
            return new Result(true, StatusCode.SERVER_EXCEPTION, "服务器异常！");
        }
        return new Result<User>(true, StatusCode.OK, "修改成功！");
    }

    @Override
    public Result findUserById(Long id) {
        Example example = new Example(User.class);
        example.createCriteria().andEqualTo("id", id);
        User user = userMapper.selectOneByExample(example);
        if (ObjectUtils.isEmpty(user) || "Y".equals(user.getDel().toString())) {
            return new Result(true, StatusCode.NOTFOUNDERROR, "该用户不存在或已被注销！");
        }
        return new Result<User>(true, StatusCode.OK, "查询成功！", user);
    }

    @Override
    public Result resetPassword(PasswordDao passwordDao) {
        //根据系统类型和手机号校验账户的有效性
        Example example = new Example(User.class);
        example.createCriteria().andEqualTo("username", passwordDao.getPhone());
        example.and(example.createCriteria().andEqualTo("stid", passwordDao.getStid()));
        User u = userMapper.selectOneByExample(example);
        if (ObjectUtils.isEmpty(u)) {
            redisUtils.del(NoahEnum.FINDCODEDIR.getCode() + passwordDao.getPhone());
            return new Result(true, StatusCode.ERROR, "该账户未注册！");
        }
        if (u.getDel().equals("Y")) {
            redisUtils.del(NoahEnum.FINDCODEDIR.getCode() + passwordDao.getPhone());
            return new Result(true, StatusCode.ERROR, "该账户已注销,不能进行修改操作！");
        }
        //手机验证码校验
        boolean hasKey = redisUtils.hasKey(NoahEnum.FINDCODEDIR.getCode() + passwordDao.getPhone());
        if (!hasKey) {
            return new Result(true, StatusCode.ERROR, "验证码已失效！");
        }
        String smsCode = (String) redisUtils.get(NoahEnum.FINDCODEDIR.getCode() + passwordDao.getPhone());
        if (!smsCode.equals(passwordDao.getSms())) {
            return new Result(true, StatusCode.ERROR, "验证码输入有误！");
        }
        //修改密码操作
        String newPassword = MD5Utils.getMD5Pwd(passwordDao.getPassword());
        u.setPassword(newPassword);
        int updateRes = userMapper.updateByPrimaryKey(u);
        if (updateRes == 0) {
            return new Result(true, StatusCode.ERROR, "重置失败！");
        }
        return new Result(true, StatusCode.OK, "重置成功！");
    }

    @Override
    public Result updateAvatar(String avatar, Long uid) {
        Example example = new Example(User.class);
        example.createCriteria().andEqualTo("id", uid);
        User u = userMapper.selectOneByExample(example);
        if (ObjectUtils.isEmpty(u)) {
            return new Result(true, StatusCode.ERROR, "该账户未注册！");
        }
        u.setAvatar(avatar);
        int updateRes = userMapper.updateByPrimaryKey(u);
        if (updateRes == 0) {
            return new Result(true, StatusCode.ERROR, "修改失败！");
        }
        return new Result(true, StatusCode.OK, "修改成功！");
    }

    @Override
    public Result updatePhone(String phone, String smsCode, Long uid) {
        Example example = new Example(User.class);
        example.createCriteria().andEqualTo("id", uid);
        User u = userMapper.selectOneByExample(example);
        if (ObjectUtils.isEmpty(u)) {
            redisUtils.del(NoahEnum.UPDATECODEDIR.getCode() + phone);
            return new Result(true, StatusCode.ERROR, "该账户未注册！");
        }
        if (u.getDel().equals("Y")) {
            redisUtils.del(NoahEnum.UPDATECODEDIR.getCode() + phone);
            return new Result(true, StatusCode.ERROR, "该账户已注销,不能进行修改操作！");
        }
        //校验短信验证码
        boolean hasKey = redisUtils.hasKey(NoahEnum.UPDATECODEDIR.getCode() + phone);
        if (!hasKey) {
            return new Result(true, StatusCode.ERROR, "验证码已失效！");
        }
        String sms = (String) redisUtils.get(NoahEnum.UPDATECODEDIR.getCode() + phone);
        if (!sms.equals(smsCode)) {
            return new Result(true, StatusCode.ERROR, "验证码输入有误！");
        }
        u.setPhone(phone);
        int updateRes = userMapper.updateByPrimaryKey(u);
        if (updateRes == 0) {
            return new Result(true, StatusCode.ERROR, "修改失败！");
        }
        return new Result(true, StatusCode.OK, "修改成功！");
    }


    /**
     * 条件查询用户信息
     *
     * @param page
     * @param limit
     * @param stid
     * @param acctid
     * @param name
     * @return
     */
    @Override
    public Result getUser(Integer page, Integer limit, Long stid, Long acctid, String name) {
        PageHelper.startPage(page, limit);
        Example example = new Example(User.class);
        example.createCriteria().andEqualTo("stid", stid).andEqualTo("acctid", acctid).andEqualTo("del", "N").andEqualTo("userPro", "0");
        if (!StringUtils.isEmpty(name)) {
            example.and(example.createCriteria().andLike("name", name + "%"));
        }
        List<User> list = userMapper.selectByExample(example);
        if (ObjectUtils.isEmpty(list)) {
            return new Result(false, StatusCode.NOTFOUNDERROR, "无用户信息");
        }
        PageInfo<User> pageInfo = new PageInfo<>(list);
        return new Result(true, StatusCode.OK, "查询成功", pageInfo);
    }

    /**
     * 根据ID查询用户信息
     *
     * @param id
     * @return
     */
    @Override
    public Result getUserById(Long id) {
        User user = userMapper.selectByPrimaryKey(id);
        if (ObjectUtils.isEmpty(user)) {
            return new Result(false, StatusCode.ERROR, "查询出错");
        }

        List<Role> list = roleMapper.getRoleById(id);
        if (!ObjectUtils.isEmpty(list)) {
            user.setList(list);
        }

        return new Result(true, StatusCode.OK, "查询成功", user);
    }

    /**
     * 修改用户信息
     *
     * @param user
     * @return
     */
    @Transactional
    @Override
    public Result updateUserRoleById(User user) {
        Example example = new Example(User.class);
        example.createCriteria().andEqualTo("id", user.getId());
        User userRes = userMapper.selectOneByExample(example);
        if (ObjectUtils.isEmpty(userRes) || "Y".equals(userRes.getDel().toString())) {
            return new Result(false, StatusCode.NOTFOUNDERROR, "该用户不存在或已被注销！");
        }
        int a = userMapper.updateByPrimaryKeySelective(user);
        if (a == 0) {
            return new Result(false, StatusCode.SERVER_EXCEPTION, "服务器异常！");
        }

        Set<Long> setoldrid = new HashSet<Long>(Arrays.asList(user.getOldrid()));
        Set<Long> nnewrid = new HashSet<Long>(Arrays.asList(user.getNewrid()));
        setoldrid.removeAll(nnewrid);
        if (!ObjectUtils.isEmpty(setoldrid)) {
            Example example1 = new Example(UserRole.class);
            example1.createCriteria().andEqualTo("uid", user.getId()).andIn("rid", setoldrid);
            int res = userRoleMapper.deleteByExample(example1);
            if (res == 0) {
                return new Result(false, StatusCode.SERVER_EXCEPTION, "服务器异常");
            }
        }

        Set<Long> oldrid = new HashSet<Long>(Arrays.asList(user.getOldrid()));
        Set<Long> setnewrid = new HashSet<Long>(Arrays.asList(user.getNewrid()));
        setnewrid.removeAll(oldrid);
        if (!ObjectUtils.isEmpty(setnewrid)) {
            int res = userRoleMapper.insertUserRole(user.getId(), setnewrid);
            if (res == 0) {
                return new Result(false, StatusCode.SERVER_EXCEPTION, "服务器异常");
            }
        }
        return new Result<User>(true, StatusCode.OK, "修改成功！");
    }

    /**
     * 根据ID删除角色
     */
    @Transactional
    @Override
    public Result delUser(Long[] id) {
        List<Long> list = new ArrayList<>(Arrays.asList(id));
        User user = new User();
        user.setDel('Y');
        Example example = new Example(User.class);
        example.createCriteria().andIn("id", list);
        int res = userMapper.updateByExampleSelective(user, example);
        if (res == 0) {
            return new Result(false, StatusCode.ERROR, "删除失败");
        }
        Example example1 = new Example(UserRole.class);
        example1.createCriteria().andIn("uid", list);
        int roleres = userRoleMapper.deleteByExample(example1);
        if (roleres == 0) {
            return new Result(false, StatusCode.ERROR, "删除失败");
        }
        return new Result(true, StatusCode.OK, "删除成功");
    }

    /**
     * 添加用户
     *
     * @param user
     * @return
     */
    @Override
    public Result addUser(User user) {
        Example example = new Example(User.class);
        example.createCriteria().andEqualTo("username", user.getUsername());
        User user1 = userMapper.selectOneByExample(example);
        if (!ObjectUtils.isEmpty(user1)) {
            return new Result(false, StatusCode.REPERROR, "账号已存在");
        }
        user.setPassword(MD5Utils.getMD5Pwd(user.getPassword()));
        user.setCreatedTime(new Date());
        user.setUserType("0");
        user.setAvatar("");
        user.setUserPro("0");
        int res = userMapper.insertSelective(user);
        if (res == 0) {
            return new Result(false, StatusCode.ERROR, "新增用户失败");
        }
        return new Result(true, StatusCode.OK, "添加用户成功", user);
    }

    /**
     * 通过手机号查找用户
     *
     * @param phone
     * @return
     */
    public Result getUserByPhone(Long stid, String phone) {
        Example example = new Example(User.class);
        example.createCriteria().andEqualTo("phone", phone);
        example.and(example.createCriteria().andEqualTo("stid", stid));
        User user = userMapper.selectOneByExample(example);
        if (ObjectUtils.isEmpty(user)) {
            return new Result(false, StatusCode.NOTFOUNDERROR, "手机号没有注册");
        }
        return new Result(true, StatusCode.OK, "查询成功");
    }

    /**
     * 分页查询企业管理账户
     *
     * @param stid
     * @param page
     * @param limit
     * @return
     */
    @Override
    public Result getProUser(Long stid, Integer page, Integer limit) {
        PageHelper.startPage(page, limit);
        List<User> list = new ArrayList<User>();
        if (!ObjectUtils.isEmpty(stid)) {
            list = userMapper.selectUserByUserProAndStid("0", stid);
        } else {
            list = userMapper.selectUserByUserPro("0");
        }
        if (ObjectUtils.isEmpty(list)) {
            return new Result(false, StatusCode.NOTFOUNDERROR, "暂无数据");
        }
        PageInfo<User> pageInfo = new PageInfo<>(list);
        return new Result(true, StatusCode.OK, "查询成功", pageInfo);
    }

    /**
     * 初始化管理用户
     *
     * @param user
     * @return
     */
    @Transactional
    @Override
    public Result addAdminUser(User user) {
        Example example = new Example(User.class);
        example.createCriteria().andEqualTo("username", user.getUsername());
        User user1 = userMapper.selectOneByExample(example);
        if (!ObjectUtils.isEmpty(user1)) {
            return new Result(false, StatusCode.REPERROR, "账号已存在");
        }
        user.setPassword(MD5Utils.getMD5Pwd(user.getPassword()));
        user.setCreatedTime(new Date());
        user.setUserType("0");
        user.setAvatar("");
        user.setUserPro("0");
        int res = userMapper.insertSelective(user);
        if (res == 0) {
            return new Result(false, StatusCode.ERROR, "新增用户失败");
        }
        UserRole userRole = new UserRole();
        userRole.setUid(user.getId());
        userRole.setRid(user.getRid());
        int roleres = userRoleMapper.insertSelective(userRole);
        if (roleres == 0) {
            return new Result(false, StatusCode.ERROR, "新增用户失败");
        }
        Set<Long> mid = menuMapper.getMid(user.getStid(), user.getAcctid());
        if (ObjectUtils.isEmpty(mid)) {
            return new Result(false, StatusCode.ERROR, "请先添加相关菜单信息");
        }
        Set<Long> pid = permissionMapper.getPid(user.getStid(), user.getAcctid());
        if (ObjectUtils.isEmpty(pid)) {
            return new Result(false, StatusCode.ERROR, "请先添加相关权限信息");
        }
        int midres = roleMenuMapper.insertRoleMenu(user.getAcctid(), user.getRid(), mid);
        if (midres == 0) {
            return new Result(false, StatusCode.ERROR, "添加失败");
        }
        int pidres = rolePermissionMapper.insertRolePermission(user.getAcctid(), user.getRid(), pid);
        if (pidres == 0) {
            return new Result(false, StatusCode.ERROR, "添加失败");
        }
        return new Result(true, StatusCode.OK, "添加用户成功");
    }

    /**
     * 查询用户的数量
     * @return
     */
    @Override
    public Result getCount(){
        HashMap<String,Integer> map = new HashMap<>();
        Example example = new Example(User.class);
        int count = userMapper.selectCountByExample(example);
        example.createCriteria().andEqualTo("userPro","0");
        int procount = userMapper.selectCountByExample(example);
        map.put("user",count);
        map.put("userPro",procount);
        return new Result(true,StatusCode.OK,"查询成功",map);
    }

}
